
-- simple day/night cycle
local function DayNight()
	
	if( atmos.Dynamic == false ) then return end
	if( !atmos.Allowed(game.GetMap()) ) then return end
	
	if( atmos.NextChange > CurTime() ) then return end
	
	-- delay if storming
	if( atmos.Storming ) then atmos.NextChange = atmos.NextChange + 120 end

	if( atmos.CurrentSky >= 4 ) then
	
		atmos.CurrentSky = 1;
	
	else
	
		atmos.CurrentSky = atmos.CurrentSky + 1;
		
	end
	
	for k,v in pairs( player.GetAll() ) do
		
		net.Start( "atmoschangesky" )
		net.WriteFloat( atmos.CurrentSky )
		net.Send( v )
		
	end
	
	atmos.NextChange = CurTime() + atmos.DynamicInterval;

end
hook.Add( "Think", "AtmosDayNightThink", DayNight );

local function StormThink()
	
	if( !atmos.CanStorm(game.GetMap()) ) then return end
	
	if( atmos.EnableStorms == false ) then return end
	
	if( CurTime() > atmos.NextStorm ) then
		
		-- if its already storming that means an admin forced it, so delay
		if( atmos.Storming ) then atmos.NextStorm = CurTime() + atmos.StormInterval end
	
		for k,v in pairs( player.GetAll() ) do
			
			net.Start( "atmosrecvstorm" )
			net.WriteFloat( 1 )
			net.Send( v )
			
			atmos.Storming = true;
			
		end
		
		timer.Simple( atmos.StormDuration, function()
				
			for k,v in pairs( player.GetAll() ) do
				
				net.Start( "atmosrecvstorm" )
				net.WriteFloat( 0 )
				net.Send( v )
				
				atmos.Storming = false;
				
			end
		
		end );
		
		atmos.NextStorm = CurTime() + atmos.StormInterval;
	
	end

end
hook.Add( "Think", "AtmosStormThink", StormThink );

-- admin command to force the current sky
concommand.Add( "atmos_changesky", function( pl, cmd, args )
	
	if( !pl:IsAdmin() ) then return end
	
	local sky = tonumber(args[1]) or 1;
	
	if( sky == 0 or sky > 4 ) then 
	
		pl:PrintMessage( HUD_PRINTCONSOLE, "\n[atmos] number must be between 1 (dawn) and 4 (night).");
		
		return;
		
	end
	
	for k,v in pairs( player.GetAll() ) do
		
		net.Start( "atmoschangesky" )
		net.WriteFloat( sky )
		net.Send( v )
		
	end
	
	-- extend time till next change if an admin forces it
	atmos.NextChange = CurTime() + atmos.DynamicInterval;
	atmos.CurrentSky = sky;
	
	local enums = {}
	enums[1] = 'SKY_DAWN';
	enums[2] = 'SKY_DAY';
	enums[3] = 'SKY_DUSK';
	enums[4] = 'SKY_NIGHT';
	
	pl:PrintMessage( HUD_PRINTCONSOLE, "\n[atmos] set current sky to ".. tostring( enums[sky] ) ..".");
	
end );

-- admin command to disable dynamic change
concommand.Add( "atmos_disabledynamic", function( pl, cmd, args )
	
	if( !pl:IsAdmin() ) then return end
	
	atmos.Dynamic = false;
	
	pl:PrintMessage( HUD_PRINTCONSOLE, "\n[atmos] dynamic change disabled.");
	
end );

-- admin command to enable dynamic change
concommand.Add( "atmos_enabledynamic", function( pl, cmd, args )
	
	if( !pl:IsAdmin() ) then return end
	
	atmos.Dynamic = true;
	
	pl:PrintMessage( HUD_PRINTCONSOLE, "\n[atmos] dynamic change enabled.");
	
end );

-- admin command to set the dynamic change interval ( in seconds )
concommand.Add( "atmos_setdynamicinterval", function( pl, cmd, args )
	
	if( !pl:IsAdmin() ) then return end
	
	local default = 8*60;
	
	atmos.DynamicInterval = tonumber(args[1]) or default;
	atmos.NextChange = CurTime() + atmos.DynamicInterval;
	
	pl:PrintMessage( HUD_PRINTCONSOLE, "\n[atmos] set dynamic interval to ".. tostring(atmos.DynamicInterval) .." seconds.");
	
end );

-- command to see atmos commands
concommand.Add( "atmos_help", function( pl, cmd, args )
	
		if( pl:IsAdmin() or pl:IsSuperAdmin() ) then
	
		pl:PrintMessage( HUD_PRINTCONSOLE, "\n\n[atmos] Listing available commands" );
		pl:PrintMessage( HUD_PRINTCONSOLE, "\natmos_changesky <1-4> - change current sky for everyone" );
		pl:PrintMessage( HUD_PRINTCONSOLE, "\natmos_disabledynamic - disable dynamic changing of the sky" );
		pl:PrintMessage( HUD_PRINTCONSOLE, "\natmos_enabledynamic - enable dynamic changing of the sky" );
		pl:PrintMessage( HUD_PRINTCONSOLE, "\natmos_setdynamicinterval - set the dynamic change interval (in seconds)" );
		pl:PrintMessage( HUD_PRINTCONSOLE, "\ncl_atmos_pp <0-1> - client command to enable or disable atmos post processing\n");
		pl:PrintMessage( HUD_PRINTCONSOLE, "\ncl_atmos_start - force atmos to start on the client\n");
		pl:PrintMessage( HUD_PRINTCONSOLE, "\ncl_atmos_stop - force atmos to stop on the client\n");
		
		else
		
		pl:PrintMessage( HUD_PRINTCONSOLE, "\n\n[atmos] Listing available commands" );
		pl:PrintMessage( HUD_PRINTCONSOLE, "\ncl_atmos_pp <0-1> - client command to enable or disable atmos post processing\n");
		pl:PrintMessage( HUD_PRINTCONSOLE, "\ncl_atmos_start - force atmos to start on the client\n");
		pl:PrintMessage( HUD_PRINTCONSOLE, "\ncl_atmos_stop - force atmos to stop on the client\n");
		
		end
	
end );

-- experimental toggle for md_ironsky's clouds
local CloudState = true; -- true = on, they are on by default

concommand.Add( "atmos_toggleclouds", function( pl, cmd, args )
	
	if( !pl:IsAdmin() ) then return end
	
	if( CloudState ) then
	
		for k,v in pairs( ents.GetAll() ) do if( tostring( v:GetClass() ) == 'func_dustcloud' ) then v:Fire('TurnOff') end end
		CloudState = false;
		
	else
	
		for k,v in pairs( ents.GetAll() ) do if( tostring( v:GetClass() ) == 'func_dustcloud' ) then v:Fire('TurnOn') end end
		CloudState = true;
		
	end
	
end );

-- admin command to toggle a storm
concommand.Add( "atmos_storm", function( pl, cmd, args )
	
	if( !pl:IsAdmin() ) then return end
	
	if( !atmos.CanStorm( game.GetMap() ) ) then 
		pl:PrintMessage( HUD_PRINTCONSOLE, "\n[atmos] this map isnt setup properly for storms to work." );
		return;
	end
	
	if( atmos.Storming == false ) then
	
		for k,v in pairs( player.GetAll() ) do
		
			net.Start( "atmosrecvstorm" )
			net.WriteFloat( 1 )
			net.Send( v )
			
		end
		
		txt = "created storm.";
		
		atmos.Storming = true;
		
	else
	
		for k,v in pairs( player.GetAll() ) do
		
			net.Start( "atmosrecvstorm" )
			net.WriteFloat( 0 )
			net.Send( v )
			
		end
		
		txt = "destroyed storm.";
		
		atmos.Storming = false;
		
	end
	
	pl:PrintMessage( HUD_PRINTCONSOLE, "\n[atmos] ".. tostring( txt ) );
	
end );

-- Sync current weather to new players
function atmos.Sync( pl )
 
	if( atmos.Storming ) then
	
		net.Start( "atmosrecvstorm" )
		net.WriteFloat( 1 )
		net.Send( pl )
	
	end
	
	net.Start( "atmoschangesky" )
	net.WriteFloat( atmos.CurrentSky )
	net.Send( pl )
	
	-- sync players with the servers map data
	net.Start( "atmosRecvData" );
		net.WriteTable( { atmos.AllowedMaps, atmos.StormData } )
	net.Send( pl );
	
	-- start atmos on the client
	net.Start( 'atmosStart' )
	net.Send( pl )
	
end
hook.Add( "PlayerInitialSpawn", "atmosSync", atmos.Sync )

